package com.ericsson.common.util;

import com.ericsson.common.pojo.FTPInfoVO;
import com.jcraft.enipjsch.*;
import com.jcraft.enipjsch.ChannelSftp.LsEntry;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;

import java.io.*;
import java.util.*;


/**
 * SFTP工具类
 *
 * @author yanghai
 * @version 1.6.5
 * @created 2021-08-30 上午11:52:28
 */
public class SFtpCarrierUtilNew {

    private Logger log;
    private FTPInfoVO ftpConf;

    private int port = 22;
    private ChannelSftp sftp = null;
    private Session sshSession = null;

    public SFtpCarrierUtilNew(FTPInfoVO ftpConf, Logger log) {
        this.ftpConf = ftpConf;
        this.log = log;
    }

    /** * connect server via sftp */
    public void connect() {
        try {
            JSch jsch = new JSch();
            jsch.getSession(ftpConf.getUserName(), ftpConf.getHost(), port);
            sshSession = jsch.getSession(ftpConf.getUserName(), ftpConf.getHost(), port);
            sshSession.setPassword(ftpConf.getPassword());
            Properties sshConfig = new Properties();
            sshConfig.put("StrictHostKeyChecking", "no");
            sshSession.setConfig(sshConfig);
            sshSession.connect();
            Channel channel = sshSession.openChannel("sftp");
            channel.connect();
            sftp = (ChannelSftp) channel;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /** * 关闭资源 */
    public void disconnect(){
        if (this.sftp != null) {
            if (this.sftp.isConnected()) {
                this.sftp.quit();
                this.sftp.disconnect();
                log.info("sftp is close already");
            }
            try {
                if(this.sftp.getSession()!=null&&this.sftp.getSession().isConnected()) {
                    this.sftp.getSession().disconnect();
                }
            } catch (JSchException e) {
                log.error("this.sftp.getSession().disconnect()"+e.getMessage());
            }
        }
        if (this.sshSession != null) {
            if (this.sshSession.isConnected()) {
                this.sshSession.disconnect();
                log.info("sshSession is close already");
            }
        }
    }
    /**
     * EBM AMF 原始文件下载
     * 20210830
     * yanghai
     */
    public String batchDownLoadFileSCP(String remotPath, String localPath, boolean down, String netName,
                                       int fileSizeLimit) {
        File filePath = new File(localPath);
        FileUtil.newDirs(filePath);
        List<String> fileListDownloaded = new ArrayList<String>();
            connect();
            try {
                Vector v = listFiles(remotPath);
                if (v.size() > 0) {
                    Iterator it = v.iterator();
                    while (it.hasNext()) {
                        LsEntry entry = (LsEntry) it.next();
                        String filename = entry.getFilename();
                        SftpATTRS attrs = entry.getAttrs();
                        if (filename.length() > 40) {
                            String tempName = filename.substring(0, 14)
                                    + StringUtils.leftPad(filename.split("_")[1], 3, '0')
                                    + StringUtils.leftPad(filename.split("\\.")[3], 5, '0');
                            if (!attrs.isDir()) {
                                if (filename.indexOf("ebs") > 0
                                        && tempName.compareTo(ftpConf.getDownloadebmlogtime()) > 0) {
                                    fileListDownloaded.add(filename);
                                }
                            }
                        }
                    }
                }
                Collections.sort(fileListDownloaded, new Comparator<String>() {
                    @Override
                    public int compare(String filenameA, String filenameB) {
                        return (filenameA.substring(0, 14) + StringUtils.leftPad(filenameA.split("_")[1], 3, '0')
                                + StringUtils.leftPad(filenameA.split("\\.")[3], 5, '0'))
                                .compareTo(filenameB.substring(0, 14)
                                        + StringUtils.leftPad(filenameB.split("_")[1], 3, '0')
                                        + StringUtils.leftPad(filenameB.split("\\.")[3], 5, '0'));
                    }
                });
                // 判断是否超过限制的文件数，如果超过 只下载一个文件，否则正常下载
                if (fileListDownloaded.size() > fileSizeLimit&&down) {
                    sftp.get(remotPath + "/" + fileListDownloaded.get(fileListDownloaded.size() - 1), localPath, null, ChannelSftp.OVERWRITE);
                    log.info("=====1" + fileListDownloaded.get(fileListDownloaded.size() - 1) + "===== netName = "
                            + netName);
                } else {
                    for (int i = 0; i < fileListDownloaded.size()-1; i++) {
                        sftp.get(remotPath + "/" + fileListDownloaded.get(i), localPath, null,ChannelSftp.OVERWRITE);
                        log.info("=====2many" + fileListDownloaded.get(i) + "===== netName = " + netName);
                    }
                }
                this.disconnect();
        } catch (SftpException e) {
                log.error(e.getLocalizedMessage() + netName);
        }
        if (fileListDownloaded.size() > 2) {
            String temp = fileListDownloaded.get(fileListDownloaded.size() - 2);
            return temp.substring(0, 14) + StringUtils.leftPad(temp.split("_")[1], 3, '0')
                    + StringUtils.leftPad(temp.split("\\.")[3], 5, '0');
        } else {
            return "";
        }
    }

    /**
     * 下载5GCKPI文件，cd命令不能使用
     * @param remotePath
     * @param remoteFileName
     * @param localPath
     * @param localFileName
     * @return
     */
    public boolean downloadVgcKpiFile(String remotePath, String remoteFileName, String localPath, String localFileName) {
        try {
            File file = new File(localPath + localFileName);
            mkdirs(localPath + localFileName);
            sftp.get(remotePath+remoteFileName, new FileOutputStream(file));
            return true;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (com.jcraft.enipjsch.SftpException e) {
            e.printStackTrace();
        }
        return false;
    }


    /**
     * * 列出目录下的文件 * @param directory * 要列出的目录 * @param sftp * @return * @throws
     * SftpException
     */
    public Vector listFiles(String directory) throws SftpException {
        return sftp.ls(directory);
    }

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }

    public ChannelSftp getSftp() {
        return sftp;
    }

    public void setSftp(ChannelSftp sftp) {
        this.sftp = sftp;
    }

    public boolean downloadFile(String remotePath, String remoteFileName, String localPath, String localFileName) {
        try {
            sftp.cd(remotePath);
            File file = new File(localPath + localFileName);
            mkdirs(localPath + localFileName);
            sftp.get(remoteFileName, new FileOutputStream(file));
            return true;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (com.jcraft.enipjsch.SftpException e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 如果目录不存在就创建目录 *
     *
     * @param path
     */
    public void mkdirs(String path) {
        File f = new File(path);
        String fs = f.getParent();
        f = new File(fs);
        if (!f.exists()) {
            f.mkdirs();
        }
    }

    public static void main(String[] args) {
        FTPInfoVO ftpInfo = new FTPInfoVO();
        ftpInfo.setHost("192.168.1.230");
        ftpInfo.setUserName("root");
        ftpInfo.setPassword("1qaz#EDC");
        ftpInfo.setPath("/opt");
        ftpInfo.setPort(21);
        System.out.println("--------------------- ftpInfo:" + ftpInfo);
        SFtpCarrierUtilNew sftpCarrier = new SFtpCarrierUtilNew(ftpInfo, null);
        sftpCarrier.connect();
        System.out.println("--------------------- connect success -----------------");
        try {
            Vector v = sftpCarrier.listFiles(ftpInfo.getPath());

        } catch (SftpException e) {
            e.printStackTrace();
        }
    }

    public Set<String> download_VGCCDR(String fileNameType, String subDirs, String date, TreeSet<String> sortSet, boolean down) {
        Set<String> downFileResult=new TreeSet<>();
        try {
            connect();
            String path = this.ftpConf.getPath();
            String storePath = analysisVgcStorePath(subDirs, path);
            File storeDir = FileUtil.newDirs(storePath);

            String analysisPathResult = analysiVgcPath(path, date);
            log.info("fileNameType:" + fileNameType + "：path" + path + " date " + date + " analysiPathResult " + analysisPathResult);
            Vector v = listFiles(analysisPathResult);
            if (v.size() > 0) {
                Iterator it = v.iterator();
                while (it.hasNext()) {
                    LsEntry entry = (LsEntry) it.next();
                    String filename = entry.getFilename();
                    SftpATTRS attrs = entry.getAttrs();
                    if (!filename.equals(".") && !filename.equals("..") && !attrs.isDir()) {
                        if (!sortSet.contains(filename)) {
                            String originalName = "";
                            if (filename.contains(".gz:")) {
                                originalName = new String((filename + ".gz").getBytes("ISO-8859-1"), "UTF-8");
                            } else {
                                originalName = new String(filename.getBytes("ISO-8859-1"), "UTF-8");
                            }
                            File localFile = new File(storeDir, originalName);
                            if (!localFile.exists() && down) {
                                sftp.get(analysisPathResult + "/" + filename, storePath, null,ChannelSftp.OVERWRITE);
                                log.info("fileNameType:" + fileNameType + "download file >>>>>>:" + filename);
                                if (filename.contains(".gz")) {
                                    gzipFile(localFile);
                                }
                            }
                            downFileResult.add(filename);
                        }
                    }
                }
            }
        }catch (Exception ex){
            log.error(ex.getLocalizedMessage());
        }
        return downFileResult;
    }

    /**
     * 话单下载路径辅助方法
     *
     * @param path
     * @return
     */
    public String analysiVgcPath(String path, String date) {
        String[] strings = path.split("/");
        StringBuilder sBuilder = new StringBuilder();
        for (int i = 1; i < strings.length; i++) {
            if (i == strings.length - 1) {
                sBuilder.append("/").append(date.replaceAll("-","")+ "-").append(strings[i]);
            } else {
                sBuilder.append("/").append(strings[i]);
            }
        }
        return sBuilder.toString();
    }

    private String analysisVgcStorePath(String subDirs, String path){
        String storePath="";
        if(path.contains("CDF")){
            storePath=subDirs +File.separator+"CDF"+ File.separator + this.ftpConf.getNetElementID() + File.separator;
        }else if(path.contains("OFFLINE")){
            storePath=subDirs +File.separator+"OFFLINE"+ File.separator + this.ftpConf.getNetElementID() + File.separator;
        }else if(path.contains("ONLINE")){
            storePath=subDirs +File.separator+"ONLINE"+ File.separator + this.ftpConf.getNetElementID() + File.separator;
        }else if(path.contains("ZERO")){
            storePath=subDirs +File.separator+"ZERO"+ File.separator + this.ftpConf.getNetElementID() + File.separator;
        }else if(path.contains("BGwOutput")){
            storePath=subDirs +File.separator+"CHF"+ File.separator + this.ftpConf.getNetElementID() + File.separator;
        }
        return storePath;
    }

    private void gzipFile(File localFile) {
        Process procMv;
        String[] cmdMv = new String[3];
        cmdMv[0] = "sh";
        cmdMv[1] = "-c";
        cmdMv[2] = "/usr/bin/gzip -d "
                +localFile.getPath();
        try {
            procMv = Runtime.getRuntime().exec(cmdMv);
            BufferedReader brMv = new BufferedReader(new InputStreamReader(procMv.getInputStream()));
            String lineMv;
            while ((lineMv = brMv.readLine()) != null) {
                if (lineMv.trim().endsWith("#")) {
                    break;
                }
            }
            brMv.close();
            procMv.waitFor();
            procMv.destroy();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
